package other.xsy.passlys.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.exception.CustomConfigException;
import com.rkhd.platform.sdk.exception.XsyHttpException;
import com.rkhd.platform.sdk.http.RkhdHttpClient;
import com.rkhd.platform.sdk.http.RkhdHttpData;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.service.CustomConfigService;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;

/**
 * @ClassName: HcUtils.java
 * @author: 华诚02
 * @date: 2022年9月21日
 */
public class HcUtils {
    public static final Logger logger = LoggerFactory.getLogger();

    private static String url = "http://%s/boyi/";
    public static String GET_DATA = "getData";
    public static String EXCE_SQL = "exceSql";
    public static String EXCE_PROCESS = "exceProcess";
    public static String DB = ""; 


    public static String getUrl(String path) throws CustomConfigException {
        // 获取对象实例
        CustomConfigService instance = CustomConfigService.instance();
        // 获取配置集,返回此配置集中的所有配置项
        Map<String, String> configSet = instance.getConfigSet("ErpConfig");
        if (configSet == null) {
            url = String.format(url, "");
            return url + path;
        }
        logger.info("自定义配置：" + JSONObject.toJSONString(configSet));
        String erpUrl = configSet.get("ERPURL");
        erpUrl = StringUtils.isBlank(erpUrl) ? "" : erpUrl;
        url = String.format(url, erpUrl);
        return url + path;
    }


    /**
     * 获取实体的描述(新接口)
     *
     * @param entityName
     * @return
     * @throws Exception
     */
    @SuppressWarnings("deprecation")
    public static JSONObject getEntityDesc(String entityName) throws Exception {
        RkhdHttpData data = new RkhdHttpData();
        data.setCall_type("GET");
        data.setCallString("/rest/data/v2.0/xobjects/" + entityName + "/description");
        String res = RkhdHttpClient.instance().performRequest(data);
        return JSONObject.parseObject(res);
    }

    /**
     * 根据业务类型ID查询业务类型apikey
     * @param apiKey
     * @param entityType
     * @return
     * @throws IOException
     * @throws XsyHttpException
     */
    public static JSONObject getEntityApiKey(String apiKey,Long entityType) throws IOException, XsyHttpException {
        RkhdHttpClient instance = RkhdHttpClient.instance();
        RkhdHttpData get = RkhdHttpData.newBuilder().callType("GET").callString("/rest/data/v2.0/xobjects/" + apiKey + "/busiType").build();
        JSONObject execute = instance.execute(get, JSONObject::parseObject);
        logger.info("查询销售业务类型  apiKey: " + apiKey);
        logger.info("查询销售业务类型  result: " + execute.toJSONString());
        Integer code = execute.getInteger("code");
        if (code == null || code != 200) {
            return null;
        }
        JSONObject data = execute.getJSONObject("data");
        JSONArray records = data.getJSONArray("records");
        for (Object record : records) {
            JSONObject json = (JSONObject) record;
            Long id = json.getLong("id");
            if (id.equals(entityType)) {
                //String entityApiKey = json.getString("apiKey");
                return json;
            }
        }
        return null;
    }

    /**
     * 根据单选框的value(数值) 获取单选框的label(中文)值
     *
     * @param resJ
     * @param fieldName
     * @param optionCode
     * @return
     */
    public static String getComboboxLabel(JSONObject resJ, String fieldName, Integer optionCode) {
        if (optionCode == null) {
            return null;
        }
        Map<String, String> map = getMapsFromDescribeJson(resJ, fieldName);
        for (Entry<String, String> index : map.entrySet()) {
            if (optionCode.toString().equals(index.getValue())) {
                return index.getKey();
            }
        }
        return null;
    }

    /**
     * 根据单选框的label获取单选框的value值
     *
     * @param resJ
     * @param fieldName
     * @param label
     * @return
     */
    public static Integer getComboboxValue(JSONObject resJ, String fieldName, String label) {
        if (StringUtils.isBlank(label)) {
            return null;
        }
        Integer optionValue = null;
        Map<String, String> map = getMapsFromDescribeJson(resJ, fieldName);
        for (Entry<String, String> index : map.entrySet()) {
            label = label.replace(" ", "");
            String key = index.getKey().replace(" ", "");
            if (label.equals(key)) {
                optionValue = Integer.valueOf(index.getValue());
                break;
            }
        }
        return optionValue;
    }

    /**
     * 根据多选框的value(数值) 获取多选框的label(中文)值
     *
     * @param resJ
     * @param fieldName
     * @param valueList
     * @return
     */
    public static List<String> getComboboxLabelList(JSONObject resJ, String fieldName, Integer[] valueList) {
        List<String> labelList = new ArrayList<>();
        if (valueList == null || valueList.length <= 0) {
            return labelList;
        }
        Map<String, String> map = getMapsFromDescribeJson(resJ, fieldName, true);
        for (Entry<String, String> index : map.entrySet()) {
            for (Integer value : valueList) {
                if (index.getValue().equals(value.toString())) {
                    labelList.add(index.getKey());
                }
            }
        }
        return labelList;
    }


    /**
     * 根据中文获取多选数值
     *
     * @param multiSelectMap
     * @param propoDemand
     * @return
     */
    private Integer[] getMultiValue(Map<String, String> multiSelectMap, String propoDemand) {
        List<Integer> multiValueList = new ArrayList<>();
        if (StringUtils.isBlank(propoDemand)) {
            return null;
        }
        String[] split = propoDemand.split(",");
        for (String label : split) {
            multiSelectMap.forEach((k, v) -> {
                if (label.equals(v)) {
                    multiValueList.add(Integer.valueOf(k));
                }
            });
        }
        Integer[] multiValueArr = multiValueList.toArray(new Integer[multiValueList.size()]);
        return multiValueArr;
    }

    public static Map<String, String> getMapsFromDescribeJson(JSONObject json, String columnName) {
        Map<String, String> map = new HashMap<>();
        JSONObject dataObj = json.getJSONObject("data");
        JSONArray arrays = dataObj.getJSONArray("fields");
        for (Object index : arrays) {
            JSONObject indexJs = JSONObject.parseObject(index.toString());
            if (columnName.equals(indexJs.getString("apiKey"))) {
                JSONArray sels = indexJs.getJSONArray("selectitem");
                for (Object indexSel : sels) {
                    JSONObject selJs = JSONObject.parseObject(indexSel.toString());
                    map.put(selJs.getString("label"), selJs.getString("value"));
                }
            }
        }
        return map;
    }


    /**
     * @param json
     * @param columnName
     * @param isMultiSelect 是否多选
     * @return
     */
    public static Map<String, String> getMapsFromDescribeJson(JSONObject json, String columnName, Boolean isMultiSelect) {
        Map<String, String> map = new HashMap<>();
        JSONObject dataObj = json.getJSONObject("data");
        JSONArray arrays = dataObj.getJSONArray("fields");
        for (Object index : arrays) {
            JSONObject indexJs = (JSONObject) index;
            if (columnName.equals(indexJs.getString("apiKey"))) {
                JSONArray sels = isMultiSelect ? indexJs.getJSONArray("checkitem") : indexJs.getJSONArray("selectitem");
                for (Object indexSel : sels) {
                    JSONObject selJs = JSONObject.parseObject(indexSel.toString());
                    map.put(selJs.getString("label"), selJs.getString("value"));
                }
            }
        }
        return map;
    }


    /**
     * 拆分集合
     *
     * @param <T>           泛型对象
     * @param resList       需要拆分的集合
     * @param subListLength 每个子集合的元素个数
     * @return 返回拆分后的各个集合组成的列表
     * 代码里面用到了guava和common的结合工具类
     **/
    public static <T> List<List<T>> split(List<T> resList, int subListLength) {
        if (resList.size() <= 0 || subListLength <= 0) {
            return new ArrayList<>();
        }
        List<List<T>> ret = new ArrayList<>();
        int size = resList.size();
        if (size <= subListLength) {
            // 数据量不足 subListLength 指定的大小
            ret.add(resList);
        } else {
            int pre = size / subListLength;
            int last = size % subListLength;
            // 前面pre个集合，每个大小都是 subListLength 个元素
            for (int i = 0; i < pre; i++) {
                List<T> itemList = new ArrayList<>();
                for (int j = 0; j < subListLength; j++) {
                    itemList.add(resList.get(i * subListLength + j));
                }
                ret.add(itemList);
            }
            // last的进行处理
            if (last > 0) {
                List<T> itemList = new ArrayList<>();
                for (int i = 0; i < last; i++) {
                    itemList.add(resList.get(pre * subListLength + i));
                }
                ret.add(itemList);
            }
        }
        return ret;
    }


    /*功能描述：获取指定通用选项集的信息
     * 参数globalPickApiKey：通用选项集apiKey
     * 返回值：通用选项集内容
     */
    public static JSONArray getGlobalPicks(String globalPickApiKey) {
        RkhdHttpData data = new RkhdHttpData();
        data.setCall_type("GET");
        data.setCallString("/rest/metadata/v2.0/settings/globalPicks/" + globalPickApiKey);

        JSONArray resultArray = new JSONArray();

        try {
            String response = RkhdHttpClient.instance().performRequest(data);
            logger.debug("获取指定通用选项集的信息：" + response);
            JSONObject json = JSONObject.parseObject(response);
            if (json.getString("code").equals("0")) {
                resultArray = json.getJSONObject("data").getJSONObject("records").getJSONArray("pickOption");
            }
        } catch (Exception e) {
            logger.error("获取通用选项集【" + globalPickApiKey + "】发生异常。");
        }
        return resultArray;
    }

    /**
     * 获取通用选项集单选,根据optionCode获取optionApiKey
     *
     * @param provinceArray 指定 API 通用选项集
     * @param value         数值
     * @return optionApiKey
     */
    public static String getOptionApi(JSONArray provinceArray, Integer value) {
        if (value == null) {
            return null;
        }
        String optionApiKey = null;
        for (Object o : provinceArray) {
            JSONObject faultJson = (JSONObject) o;
            if (value.equals(faultJson.getInteger("optionCode"))) {
                optionApiKey = faultJson.getString("optionApiKey");
            }
        }
        return optionApiKey;
    }

    /**
     * 获取通用选项集单选,根据optionCode获取optionLabel
     *
     * @param provinceArray 指定 API 通用选项集
     * @param value         数值
     * @return optionApiKey
     */
    public static String getOptionLabel(JSONArray provinceArray, Integer value) {
        if (value == null) {
            return null;
        }
        String optionLabel = null;
        for (Object o : provinceArray) {
            JSONObject faultJson = (JSONObject) o;
            if (value.equals(faultJson.getInteger("optionCode"))) {
                optionLabel = faultJson.getString("optionLabel");
            }
        }
        return optionLabel;
    }


    /**
     * 获取通用选项集单选
     *
     * @param provinceArray 指定 API 通用选项集
     * @param Label         通用选项集 中文
     * @return
     */
    public static Integer getGeneralValue(JSONArray provinceArray, String Label) {
        if (StringUtils.isBlank(Label)) {
            return null;
        }
        Integer value = null;
        for (Object o : provinceArray) {
            JSONObject faultJson = (JSONObject) o;
            String optionLabel = faultJson.getString("optionLabel");
            if (Label.equals(optionLabel)) {
                value = faultJson.getInteger("optionCode");
                break;
            }
        }
        return value;
    }

    /**
     * 获取通用选项集单选,根据optionLabel获取optionApiKey
     *
     * @param provinceArray 指定 API 通用选项集
     * @param label         中文
     * @return optionApiKey
     */
    public static String getOptionApiKey(JSONArray provinceArray, String label) {
        if (label == null) {
            return null;
        }
        String optionApiKey = null;
        for (Object o : provinceArray) {
            JSONObject faultJson = (JSONObject) o;
            if (label.equals(faultJson.getString("optionLabel"))) {
                optionApiKey = faultJson.getString("optionApiKey");
            }
        }
        return optionApiKey;
    }


    public static String newSql(String sql) {
        List<String> zhantao = new ArrayList<>();
        Collections.addAll(zhantao, "深圳账套", "合肥账套", "上海账套", "香港账套");

        List<String> dbs = new ArrayList<>();
        Collections.addAll(dbs, "UFDATA_888_2018", "UFDATA_188_2018", "UFDATA_890_2021", "UFDATA_588_2019");
        String newSql = "";
        for (int i = 0; i < zhantao.size(); i++) {
            String ztStr = zhantao.get(i);
            String dbStr = dbs.get(i);
            newSql = newSql + sql;

            newSql = newSql.replace("DBXXX", dbStr).replace("ZTXXX", ztStr);
            if (i == zhantao.size() - 1) {
                continue;
            }
            newSql += " union all ";
        }
        return newSql;
    }

//    public static void main(String[] args) throws Exception {
//        JSONObject account = getEntityDesc("account");
//        System.err.println(account.toJSONString());
//    }



    /**
     * 加
     * @param v1
     * @param v2
     * @return
     */
    public static double bgAdd(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * 减
     * @param v1
     * @param v2
     * @return
     */
    public static double bgSub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).doubleValue();
    }
}
